package com.tanklab.signature.common.util;


public class computeUtil {
    public static void main(String[] args) {
        String num1 = "01.1";
        String num2 = "02.2222222";

        String sum = addLargeNumbers(num1, num2);
        String difference = subtractLargeNumbers(num1, num2);
        String product = multiplyLargeNumbers(num1, num2);

        System.out.println("Sum: " + sum);
        System.out.println("Difference: " + difference);
        System.out.println("Product: " + product);
    }

    public static boolean isGreaterThanZero(String num) {//判断是否为非正数，若为非正数则为false
        // Remove leading zeros and any negative sign
        num = num.replaceFirst("^0+", "");
        if (num.startsWith("-")) {
            return false;
        }
        return !num.isEmpty() && !num.equals("0");
    }

    public static String addLargeNumbers(String num1, String num2) {
            num1 = num1.replaceFirst("^0+", "");
            num2 = num2.replaceFirst("^0+", "");

            String[] parts1 = num1.split("\\.");
            String[] parts2 = num2.split("\\.");

            String intPart1 = parts1[0];
            String fracPart1 = parts1.length > 1 ? parts1[1] : "";
            String intPart2 = parts2[0];
            String fracPart2 = parts2.length > 1 ? parts2[1] : "";

            int maxFracLength = Math.max(fracPart1.length(), fracPart2.length());
            fracPart1 = padRightWithZeros(fracPart1, maxFracLength);
            fracPart2 = padRightWithZeros(fracPart2, maxFracLength);

            String fracSum = addStrings(fracPart1, fracPart2);
            int carry = fracSum.length() > maxFracLength ? 1 : 0;
            if (carry == 1) {
                fracSum = fracSum.substring(1);
            }

            String intSum = addStrings(intPart1, intPart2);
            if (carry == 1) {
                intSum = addStrings(intSum, "1");
            }

            intSum = intSum.replaceFirst("^0+", "");
            return fracSum.isEmpty() ? intSum : intSum + "." + fracSum;
        }

    public static String subtractLargeNumbers(String num1, String num2) {
        // Remove leading zeros
        num1 = num1.replaceFirst("^0+", "");
        num2 = num2.replaceFirst("^0+", "");

        // Determine which number is larger
        boolean isNegative = false;
        if (compareNumbers(num1, num2) < 0) {
            String temp = num1;
            num1 = num2;
            num2 = temp;
            isNegative = true;
        }

        // Split into integer and fractional parts
        String[] parts1 = num1.split("\\.");
        String[] parts2 = num2.split("\\.");

        String intPart1 = parts1[0];
        String fracPart1 = parts1.length > 1 ? parts1[1] : "";
        String intPart2 = parts2[0];
        String fracPart2 = parts2.length > 1 ? parts2[1] : "";

        // Pad fractional parts
        int maxFracLength = Math.max(fracPart1.length(), fracPart2.length());
        fracPart1 = padRightWithZeros(fracPart1, maxFracLength);
        fracPart2 = padRightWithZeros(fracPart2, maxFracLength);

        // Subtract fractional parts
        String fracDiff = subtractStrings(fracPart1, fracPart2);
        int borrow = fracDiff.startsWith("-") ? 1 : 0;
        if (borrow == 1) {
            fracDiff = subtractStrings("1" + padRightWithZeros("", maxFracLength), fracDiff.substring(1));
        }

        // Subtract integer parts
        String intDiff = subtractStrings(intPart1, intPart2);
        if (borrow == 1) {
            intDiff = subtractStrings(intDiff, "1");
        }

        // Remove leading zeros
        intDiff = intDiff.replaceFirst("^0+", "");

        String result = fracDiff.isEmpty() ? intDiff : intDiff + "." + fracDiff;
        return isNegative ? "-" + result : result;
    }

    public static int compareNumbers(String num1, String num2) {
        // Remove leading zeros
        num1 = num1.replaceFirst("^0+(?!$)", "");
        num2 = num2.replaceFirst("^0+(?!$)", "");

        // Split into integer and fractional parts
        String[] parts1 = num1.split("\\.");
        String[] parts2 = num2.split("\\.");

        String intPart1 = parts1[0];
        String fracPart1 = parts1.length > 1 ? parts1[1] : "";
        String intPart2 = parts2[0];
        String fracPart2 = parts2.length > 1 ? parts2[1] : "";

        // Compare integer parts
        int intComparison = compareIntegerParts(intPart1, intPart2);
        if (intComparison != 0) return intComparison;

        // Compare fractional parts
        return compareFractionalParts(fracPart1, fracPart2);
    }

    private static int compareIntegerParts(String intPart1, String intPart2) {
        // Compare lengths first
        if (intPart1.length() != intPart2.length()) {
            return intPart1.length() > intPart2.length() ? 1 : -1;
        }
        // Compare lexicographically
        return intPart1.compareTo(intPart2);
    }

    private static int compareFractionalParts(String fracPart1, String fracPart2) {
        // Pad the shorter fractional part with zeros
        int maxFracLength = Math.max(fracPart1.length(), fracPart2.length());
        fracPart1 = padRightWithZeros2(fracPart1, maxFracLength);
        fracPart2 = padRightWithZeros2(fracPart2, maxFracLength);
        // Compare lexicographically
        int fracComparison = fracPart1.compareTo(fracPart2);
        return fracComparison > 0 ? 1 : (fracComparison < 0 ? -1 : 0);
    }

    private static String padRightWithZeros2(String s, int length) {
        StringBuilder sb = new StringBuilder(s);
        while (sb.length() < length) {
            sb.append('0');
        }
        return sb.toString();
    }

        public static String multiplyLargeNumbers(String num1, String num2) {
            num1 = num1.replaceFirst("^0+", "");
            num2 = num2.replaceFirst("^0+", "");

            String[] parts1 = num1.split("\\.");
            String[] parts2 = num2.split("\\.");

            String intPart1 = parts1[0];
            String fracPart1 = parts1.length > 1 ? parts1[1] : "";
            String intPart2 = parts2[0];
            String fracPart2 = parts2.length > 1 ? parts2[1] : "";

            int totalFracLength = fracPart1.length() + fracPart2.length();
            String num1Full = intPart1 + fracPart1;
            String num2Full = intPart2 + fracPart2;

            String product = multiplyStrings(num1Full, num2Full);

            if (totalFracLength > 0) {
                product = padLeftWithZeros(product, totalFracLength + 1);
                int insertPos = product.length() - totalFracLength;
                product = product.substring(0, insertPos) + "." + product.substring(insertPos);
            }

            return product.replaceFirst("^0+", "").replaceFirst("\\.$", "");
        }

        private static String addStrings(String num1, String num2) {
            StringBuilder result = new StringBuilder();

            int maxLength = Math.max(num1.length(), num2.length());
            num1 = new StringBuilder(num1).reverse().toString();
            num2 = new StringBuilder(num2).reverse().toString();

            int carry = 0;
            for (int i = 0; i < maxLength; i++) {
                int digit1 = i < num1.length() ? num1.charAt(i) - '0' : 0;
                int digit2 = i < num2.length() ? num2.charAt(i) - '0' : 0;

                int sum = digit1 + digit2 + carry;
                carry = sum / 10;
                result.append(sum % 10);
            }

            if (carry != 0) {
                result.append(carry);
            }

            return result.reverse().toString();
        }

        private static String subtractStrings(String num1, String num2) {
            StringBuilder result = new StringBuilder();

            int maxLength = Math.max(num1.length(), num2.length());
            num1 = new StringBuilder(num1).reverse().toString();
            num2 = new StringBuilder(num2).reverse().toString();

            int borrow = 0;
            for (int i = 0; i < maxLength; i++) {
                int digit1 = i < num1.length() ? num1.charAt(i) - '0' : 0;
                int digit2 = i < num2.length() ? num2.charAt(i) - '0' : 0 + borrow;

                if (digit1 < digit2) {
                    digit1 += 10;
                    borrow = 1;
                } else {
                    borrow = 0;
                }

                result.append(digit1 - digit2);
            }

            while (result.length() > 1 && result.charAt(result.length() - 1) == '0') {
                result.setLength(result.length() - 1);
            }

            return result.reverse().toString();
        }

        private static String multiplyStrings(String num1, String num2) {
            int len1 = num1.length();
            int len2 = num2.length();
            int[] product = new int[len1 + len2];

            for (int i = len1 - 1; i >= 0; i--) {
                for (int j = len2 - 1; j >= 0; j--) {
                    int mul = (num1.charAt(i) - '0') * (num2.charAt(j) - '0');
                    int sum = product[i + j + 1] + mul;

                    product[i + j + 1] = sum % 10;
                    product[i + j] += sum / 10;
                }
            }

            StringBuilder result = new StringBuilder();
            for (int num : product) {
                if (!(result.length() == 0 && num == 0)) {
                    result.append(num);
                }
            }

            return result.length() == 0 ? "0" : result.toString();
        }

        private static String padRightWithZeros(String str, int length) {
            StringBuilder padded = new StringBuilder(str);
            while (padded.length() < length) {
                padded.append('0');
            }
            return padded.toString();
        }

        private static String padLeftWithZeros(String str, int length) {
            StringBuilder padded = new StringBuilder(str);
            while (padded.length() < length) {
                padded.insert(0, '0');
            }
            return padded.toString();
        }
    }
